package com.jj.service;

import com.jj.net.kcp.KcpState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Copyrights: QidianGroup@JJ
 *
 * @author: LuHan
 * @date: 2018/1/15, 10:43
 */

@RestController
@RequestMapping(path="/conv")
@Component
public class ConvService {
    private static Logger logger = LoggerFactory.getLogger(ConvService.class);
    private AtomicInteger convIdx = new AtomicInteger(1);
    private Map<Integer, Long> conv2Uid = new HashMap<>();
    private Map<Long, Integer> uid2Conv = new HashMap<>();

    @RequestMapping(path = "status")
    public Map<Long, Integer> status(){
        return uid2Conv;
    }

    @Value("${kcp.host}")
    public String host;
    @Value("${kcp.port}")
    public Integer port;


    public synchronized Integer lookup(Long uid){
        return uid2Conv.get(uid);
    }

    /**
     *
     * @param uid
     * @return
     */
    public synchronized int getConv(long uid){
        Integer conv = uid2Conv.get(uid);
        if(conv == null){
            conv = convIdx.getAndIncrement();
            conv2Uid.put(conv, uid);
            uid2Conv.put(uid, conv);
            logger.info("bind user:{} to conv:{}", uid, conv);
        }
        return conv;
    }

    /**
     * return 0 if not found
     * @param conv
     * @return
     */
    public synchronized long getUid(int conv){
        Long uid = conv2Uid.get(conv);
        if(uid == null){
            return 0L;
        }else{
            return uid;
        }
    }

    /**
     * clear resource
     * @param uid
     */
    public synchronized void removeUID(long uid){
        logger.debug("remove Conv for {}", uid);

        Integer conv = uid2Conv.remove(uid);
        if(conv != null){
            conv2Uid.remove(conv);
            logger.debug("remove {} kcp session", uid);
        }
    }

    public synchronized KcpState getKcpState(long uid){
        Integer conv = uid2Conv.get(uid);
        if(conv == null){
            conv = convIdx.getAndIncrement();
            conv2Uid.put(conv, uid);
            uid2Conv.put(uid, conv);
            logger.info("bind user:{} to conv:{}", uid, conv);
        }
        KcpState kcpState = new KcpState();
        kcpState.conv = conv;
        kcpState.host = host;
        kcpState.port = port;
        return kcpState;
    }
}
